using System.Collections.Generic;
using System.Text.Json;

namespace ConsentManagementProviderLib.Json
{
	internal static class JsonUnwrapper
	{
		public static SpConsents UnwrapSpConsentsAndroid(string json)
		{
			SpConsentsWrapperAndroid spConsentsWrapperAndroid = JsonSerializer.Deserialize<SpConsentsWrapperAndroid>(json);
			SpGdprConsent gdpr = null;
			SpCcpaConsent ccpa = null;
			if (spConsentsWrapperAndroid.gdpr != null)
			{
				gdpr = UnwrapSpGdprConsentAndroid(spConsentsWrapperAndroid.gdpr);
			}
			if (spConsentsWrapperAndroid.ccpa != null)
			{
				ccpa = UnwrapSpCcpaConsentAndroid(spConsentsWrapperAndroid.ccpa);
			}
			return new SpConsents(gdpr, ccpa);
		}

		private static SpCcpaConsent UnwrapSpCcpaConsentAndroid(CcpaConsentWrapper wrappedCcpa)
		{
			return new SpCcpaConsent(new CcpaConsent(wrappedCcpa.uuid, wrappedCcpa.status, wrappedCcpa.uspstring, wrappedCcpa.rejectedVendors, wrappedCcpa.rejectedCategories, wrappedCcpa.childPmId, wrappedCcpa.applies, wrappedCcpa.signedLspa, wrappedCcpa.webConsentPayload, null));
		}

		public static SpGdprConsent UnwrapSpGdprConsentAndroid(SpGdprConsentWrapperAndroid wrappedGdpr)
		{
			GdprConsent gdprConsent = new GdprConsent
			{
				uuid = wrappedGdpr.uuid,
				euconsent = wrappedGdpr.euconsent,
				TCData = wrappedGdpr.tcData,
				grants = new Dictionary<string, SpVendorGrant>()
			};
			foreach (KeyValuePair<string, Dictionary<string, object>> grant in wrappedGdpr.grants)
			{
				Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
				bool vendorGrant = false;
				if (grant.Value.ContainsKey("granted"))
				{
					vendorGrant = ((JsonElement)grant.Value["granted"]).GetBoolean();
				}
				if (grant.Value.ContainsKey("purposeGrants"))
				{
					foreach (JsonProperty item in ((JsonElement)grant.Value["purposeGrants"]).EnumerateObject())
					{
						dictionary.Add(item.Name, item.Value.GetBoolean());
					}
				}
				gdprConsent.grants[grant.Key] = new SpVendorGrant(vendorGrant, dictionary);
			}
			return new SpGdprConsent(gdprConsent);
		}

		public static SpCustomConsentAndroid UnwrapSpCustomConsentAndroid(string spConsentsJson)
		{
			return JsonSerializer.Deserialize<SpCustomConsentAndroid>(spConsentsJson);
		}

		public static GdprConsent UnwrapGdprConsent(string json)
		{
			return UnwrapGdprConsent(JsonSerializer.Deserialize<GdprConsentWrapper>(json));
		}

		public static SpConsents UnwrapSpConsents(string json)
		{
			SpConsentsWrapper spConsentsWrapper = JsonSerializer.Deserialize<SpConsentsWrapper>(json);
			SpGdprConsent gdpr = null;
			if (spConsentsWrapper.gdpr != null)
			{
				gdpr = UnwrapSpGdprConsent(spConsentsWrapper.gdpr);
			}
			SpCcpaConsent ccpa = null;
			if (spConsentsWrapper.ccpa != null)
			{
				ccpa = UnwrapSpCcpaConsent(spConsentsWrapper.ccpa);
			}
			return new SpConsents(gdpr, ccpa);
		}

		private static SpGdprConsent UnwrapSpGdprConsent(SpGdprConsentWrapper wrappedGdpr)
		{
			bool boolean = ((JsonElement)wrappedGdpr.applies).GetBoolean();
			GdprConsent consents = UnwrapGdprConsent(wrappedGdpr.consents);
			return new SpGdprConsent(boolean, consents);
		}

		private static GdprConsent UnwrapGdprConsent(GdprConsentWrapper wrapped)
		{
			GdprConsent gdprConsent = new GdprConsent
			{
				applies = wrapped.applies,
				uuid = wrapped.uuid,
				webConsentPayload = wrapped.webConsentPayload,
				euconsent = wrapped.euconsent,
				TCData = wrapped.TCData,
				grants = new Dictionary<string, SpVendorGrant>()
			};
			foreach (KeyValuePair<string, SpVendorGrantWrapper> grant in wrapped.grants)
			{
				bool boolean = ((JsonElement)grant.Value.vendorGrant).GetBoolean();
				Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
				if (grant.Value != null)
				{
					foreach (KeyValuePair<string, object> purposeGrant in grant.Value.purposeGrants)
					{
						dictionary.Add(purposeGrant.Key, ((JsonElement)purposeGrant.Value).GetBoolean());
					}
				}
				gdprConsent.grants[grant.Key] = new SpVendorGrant(boolean, dictionary);
			}
			JsonElement valueJsonElement = getValueJsonElement((JsonElement)wrapped.consentStatus, "granularStatus");
			gdprConsent.consentStatus = UnwrapConsentStatus(valueJsonElement, wrapped.consentStatus);
			return gdprConsent;
		}

		private static ConsentStatus UnwrapConsentStatus(JsonElement granularStatusWrapped, object wrappedconsentStatus)
		{
			return new ConsentStatus(granularStatus: (granularStatusWrapped.ValueKind == JsonValueKind.Undefined) ? null : new GranularStatus(getStringJsonElement(granularStatusWrapped, "vendorConsent"), getStringJsonElement(granularStatusWrapped, "vendorLegInt"), getStringJsonElement(granularStatusWrapped, "purposeConsent"), getStringJsonElement(granularStatusWrapped, "purposeLegInt"), getBoolJsonElement(granularStatusWrapped, "previousOptInAll"), getBoolJsonElement(granularStatusWrapped, "defaultConsent")), rejectedAny: getBoolJsonElement((JsonElement)wrappedconsentStatus, "rejectedAny"), rejectedLI: getBoolJsonElement((JsonElement)wrappedconsentStatus, "rejectedLI"), consentedAll: getBoolJsonElement((JsonElement)wrappedconsentStatus, "consentedAll"), consentedToAny: getBoolJsonElement((JsonElement)wrappedconsentStatus, "consentedToAny"), vendorListAdditions: getBoolJsonElement((JsonElement)wrappedconsentStatus, "vendorListAdditions"), legalBasisChanges: getBoolJsonElement((JsonElement)wrappedconsentStatus, "legalBasisChanges"), hasConsentData: getBoolJsonElement((JsonElement)wrappedconsentStatus, "hasConsentData"), rejectedVendors: getObjectJsonElement((JsonElement)wrappedconsentStatus, "rejectedVendors"), rejectedCategories: getObjectJsonElement((JsonElement)wrappedconsentStatus, "rejectedCategories"));
		}

		private static JsonElement getValueJsonElement(JsonElement element, string name)
		{
			if (element.TryGetProperty(name, out var value))
			{
				return value;
			}
			return default(JsonElement);
		}

		private static bool? getBoolJsonElement(JsonElement element, string name)
		{
			JsonElement valueJsonElement = getValueJsonElement(element, name);
			if (valueJsonElement.ValueKind == JsonValueKind.Undefined)
			{
				return null;
			}
			return valueJsonElement.GetBoolean();
		}

		private static string? getStringJsonElement(JsonElement element, string name)
		{
			JsonElement valueJsonElement = getValueJsonElement(element, name);
			if (valueJsonElement.ValueKind == JsonValueKind.Undefined)
			{
				CmpDebugUtil.LogWarning(name + " == JsonValueKind.Undefined! Unable to unwrap!");
				return null;
			}
			return valueJsonElement.ToString();
		}

		private static object getObjectJsonElement(JsonElement element, string name)
		{
			JsonElement valueJsonElement = getValueJsonElement(element, name);
			if (valueJsonElement.ValueKind == JsonValueKind.Undefined)
			{
				CmpDebugUtil.LogWarning(name + " == JsonValueKind.Undefined! Unable to unwrap!");
				return null;
			}
			return valueJsonElement;
		}

		private static SpCcpaConsent UnwrapSpCcpaConsent(SpCcpaConsentWrapper wrappedCcpa)
		{
			bool boolean = ((JsonElement)wrappedCcpa.applies).GetBoolean();
			CcpaConsent consents = UnwrapCcpaConsent(wrappedCcpa.consents);
			return new SpCcpaConsent(boolean, consents);
		}

		private static CcpaConsent UnwrapCcpaConsent(CcpaConsentWrapper wrapped)
		{
			ConsentStatus consentStatus = UnwrapConsentStatus(getValueJsonElement((JsonElement)wrapped.consentStatus, "granularStatus"), wrapped.consentStatus);
			return new CcpaConsent(wrapped.uuid, wrapped.status, wrapped.uspstring, wrapped.rejectedVendors, wrapped.rejectedCategories, "", wrapped.applies, null, wrapped.webConsentPayload, consentStatus);
		}
	}
}
